home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 10
/
The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso
/
PC_SIGCD
/
05
/
6
/
DISK0564.ZIP
/
SOURCE.ARC
/
RM.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-02-04
|
21KB
|
617 lines
TITLE RM - MSDOS FILE DELETE UTILITY
PAGE 55,132
;**********************************************************************
; THIS PROGRAM DELETES ONE OR MORE FILES, OR (WITH THE /R SWITCH)
; DIRECTORIES.
;
; USAGE (afn = ambiguous file name):
;
; RM afn1 afn2 ... - deletes the named file(s)
;
; SWITCHES (OPTIONAL):
;
; RM/F - remove write-protected files without warning
;
; RM/I - query before each deletion
;
; RM/R - allows deleting directories (recursively).
; (this is DANGEROUS, especially without the /I switch)
;
; RM/V - "verbose" mode, shows name of each file deleted.
;************************************************************************
; BY: JON DART
; 3012 HAWTHORN ST.,
; SAN DIEGO, CA 92104
;************************************************************************
; TO BUILD RM.EXE:
; MASM RM,RM,NUL,NUL
; LINK RM,RM,NUL,ASM
; EXEPACK RM.EXE RM2.EXE
; DEL RM.EXE
; REN RM2.EXE=RM.EXE
;************************************************************************
; Version 3.2, 04-Feb-89 fixes to CHECKWILD
; Version 3.1, 19-Jan-89 another fix to FIXPATH; relinked.
; Version 3.0, 24-Sep-88 bug fix in FIXPATH; relinked. Version made
; consistent with MV and CP.
; Version 1.6, 16-Feb-88 assembles under MASM 5.0, uses GETARGS
; for argument processing.
; Version 1.5, 24-Oct-86 switch parser modified, recognizes -rv
; form as well as -r -v
; Version 1.4, 10-Sep-86 (fixes prompt for write-protected files)
; Version 1.3, 19-Jul-86 (fixes gross bugs in wildcard handling)
; Version 1.2, 06-Jul-86 (changes to memory alloc., accepts hyphen
; as switch char., assembles under masm 4.0)
; Version 1.1, 03-Jul-86 (bug fixes)
; Version 1.0, 30-Jun-86
;************************************************************************
DOSSEG
.MODEL SMALL
PATHSIZE EQU 65 ;MAX. SIZE OF DOS PATHNAME, +1
MAXLEVEL EQU 12 ;MAX NESTING LEVEL FOR DIRECTORIES
MAXARGS EQU 40 ;MAXIMUM # OF COMMAND LINE ARGUMENTS
FALSE EQU 0
TRUE EQU 0FFH
CONFIRM EQU FALSE ;"CONFIRM BEFORE DELETE" DEFAULT
VERBOSE EQU FALSE ;"VERBOSE" OPTION (DEFAULT VALUE)
GOOFPROOF EQU TRUE ;CONFIRM BEFORE DELETING *.*
BIT$DIR EQU 00010000B ;BIT IN ATTRIBUTE FOR DIRECTORY
BIT$RO EQU 00000001B ;BIT IN ATTRIBUTE FOR WRITE-PROTECT
.XLIST
INCLUDE ASCII.DEF
INCLUDE MSDOS2.DEF
INCLUDE MACROS.DEF
.LIST
RMINFO STRUC
NEWDIR DW 1 DUP (?) ;FLAG, =1 IF NEW DIRECTORY CREATED
PATHTYPE DB 2 DUP (?) ;TYPE OF SOURCE (0 IF UFN)
ARG DB PATHSIZE DUP (?) ;FIRST ARGUMENT (SOURCE)
SPATH DB PATHSIZE DUP (?) ;SOURCE SEARCH PATH
SPREFIX DB PATHSIZE DUP (?) ;SOURCE LEAD-IN PATH
SCRATCH DB PATHSIZE DUP (?) ;SCRATCH AREA
FULLNAME DB PATHSIZE DUP (?) ;UNAMBIGUOUS SOURCE NAME
DTA DB 128 DUP (?) ;DTA FOR SEARCH FN.
RMINFO ENDS
RMSTRUCSIZE EQU 5*PATHSIZE+135 ;SIZE OF STRUCTURE
.DATA
;
; FIXED DATA AREA:
;
MSG1 DB 'RM Version 3.2 by Jon Dart (04-Feb-89)',CR,LF,CR,LF
DB 'USAGE:',CR,LF,CR,LF
DB 'RM [-F -I -R -V] file1 file2 ... deletes the named file(s)',CR,LF,CR,LF
DB 'SWITCHES (OPTIONAL):',CR,LF,CR,LF
DB '-F remove write-protected files without warning',CR,LF
DB CR,LF
DB '-I query before delete',CR,LF
DB CR,LF
DB '-R allow recursive deletion of directories',CR,LF
DB CR,LF
DB '-V echo file names as they are deleted',CR,LF
DB 0
MSG2 DB ': file not found.',CR,LF,0
MSG3 DB ': directory.',CR,LF,0
MSG4 DB ' : OK to delete [Y or N]? ',0
MSG5 DB ": can't remove.",CR,LF,0
MSG6 DB ': file is R/O. '
MSG6A DB 'Are you SURE [Y or N]? ',0
MSG7 DB "Directories nested too deep.",CR,LF,0
; MSG8 DB "Insufficient memory for buffers.",CR,LF,0
MSG9 DB ": Illegal switch.",CR,LF,0
MSG10 DB "Too many arguments.",CR,LF,0
MSG11 DB ' directory. Enter it [Y or N]? ',0
MSG12 DB ' directory. Delete it [Y or N]? ',0
MSG13 DB '? ',0
WILD DB '*.*',0
SWLIST DB 'FIRV',0 ;LIST OF LEGAL SWITCHES
.STACK
DB 512 DUP (?)
.DATA?
; UNINITIALIZED DATA AND BUFFER AREAS
RBASE DW 1 DUP (?) ;POINTER TO MVSTRUC IN RSTACK
LEVEL DW 1 DUP (?) ;RECURSION LEVEL
DRIVE DW 1 DUP (?) ;SOURCE DRIVE (0 = DEFAULT)
FFLAG DW 1 DUP (?) ;FORCE FLAG
IFLAG DW 1 DUP (?) ;CONFIRM FLAG
RFLAG DW 1 DUP (?) ;RECURSIVE FLAG
VFLAG DW 1 DUP (?) ;VERBOSE FLAG
FNAME_START DW 1 DUP (?) ;USED BY CHECKWILD
NUMARGS DW 1 DUP (?) ;NUMBER OF ARGUMENTS ON COMMAND LINE
ARGPTRS DW MAXARGS DUP (?) ;POINTERS TO START OF ARGUMENTS
ARGBUF DB 256 DUP (?) ;BUFFER FOR ARGUMENTS
RSTACK RMINFO MAXLEVEL DUP (<>) ;RECURSION STACK
PAGE +
.CODE
EXTRN CPYCNT:NEAR,UC:NEAR,UCSTR:NEAR,CRLF:NEAR
EXTRN ERRORMSG:NEAR,COUT:NEAR,CIN:NEAR,CLRCO:NEAR
EXTRN SKIPSP:NEAR,TYPTX:NEAR,ERRORMSG:NEAR,CLRCO:NEAR
EXTRN CMDSRC:NEAR,FIXPATH:NEAR,TYPE_DIR:ABS,TYPE_AFN:ABS
EXTRN TYPE_UFN:ABS,TYPE_DSP:ABS,TYPE_DRV:ABS,TYPE_UNK:ABS
EXTRN GETYORN:NEAR
EXTRN GETARGS:NEAR
;*********************
;* MACRO DEFINITIONS *
;*********************
ADDR MACRO REG,OFFST ;COMPUTE ADDRESS OFFSET FROM BASE REGISTER (BX)
MOV REG,BX
ADD REG,OFFST
ENDM
COPYPATH MACRO SOURCE,DEST ;COPY PATHNAME FROM SOURCE TO DEST
ADDR SI,SOURCE
ADDR DI,DEST
MOV CX,PATHSIZE
CALL CPYCNT
ENDM
ERROR MACRO ERRNUM ;SHOW ERROR MESSAGE
PUSH DS
MOV AX,DGROUP
MOV DS,AX
MOV DX,OFFSET MSG&ERRNUM
CALL ERRORMSG
POP DS
ENDM
;**********************
; PROGRAM ENTRY POINT *
;**********************
ENTRY:
TEST_DOS2 ;TEST FOR DOS 2.0, EXIT IF DOS 1
MOV AX,DGROUP
MOV ES,AX
MOV BX,(80H) ;GET BYTE COUNT FOR COMMAND LINE
CMP [BX],BYTE PTR 0
JE USEMSG ;IF NO COMMAND TAIL
PUSH BX
MOV DL,[BX]
MOV DH,0
ADD BX,DX
INC BX
MOV [BX],BYTE PTR 0 ;PUT 0 BYTE AT END OF COMMAND LINE
POP BX
INC BX
MOV SI,OFFSET ARGPTRS
MOV DI,OFFSET ARGBUF
MOV CX,MAXARGS
CALL GETARGS ;COLLECT COMMAND LINE ARGUMENTS
JNB L_2 ;IF OK
TOOMANY:
ERROR 10 ;TOO MANY ARGUMENTS (PRETTY UNLIKELY)
MOV AL,10 ;SET EXIT CODE
JMP EXIT2
L_2: CMP CX,0
JG L_3 ;IF AT LEAST 1 ARG
USEMSG: ERROR 1 ;NO ARGUMENTS, SHOW CORRECT USAGE
MOV AL,1 ;SET ERROR CODE
JMP EXIT2 ;EXIT 2 DOS
L_3:
MOV AX,ES
MOV DS,AX ;SET DATA SEG TO VARIABLE AREA
MOV BYTE PTR IFLAG,CONFIRM ;SET CONFIRM FLAG DEFAULT
MOV BYTE PTR VFLAG,VERBOSE ;SET VERBOSE FLAG DEFAULT
MOV BYTE PTR RFLAG,FALSE ;SET RECURSIVE FLAG DEFAULT
MOV BYTE PTR FFLAG,FALSE ;SET FORCE FLAG DEFAULT
MOV WORD PTR LEVEL,0 ;ZERO RECURSION LEVEL
MOV BYTE PTR DRIVE,0 ;SET DRIVE DEFAULT
;***************************
; COLLECT SWITCHES, IF ANY *
;***************************
MOV SI,OFFSET ARGPTRS
NEXTSW:
MOV BX,WORD PTR [SI] ;POINT TO ARGUMENT
MOV AL,BYTE PTR [BX] ;GET 1ST CHAR.
CMP AL,'-'
JE GOTSW ;IF SWITCH SPECIFIED
CMP AL,'/'
JE GOTSW
JMP GETFILES
GOTSW:
INC BX ;SKIP OVER SWITCH CHARACTER
MOV AL,BYTE PTR [BX]
SWLOOP:
CALL UC ;MAKE SWITCH UPPER CASE
PUSH BX
MOV BX,OFFSET SWLIST
CALL CMDSRC ;SEARCH LIST OF VALID SWITCHES
POP BX
MOV AH,0
ADD AX,AX ;NOT FOUND IN LIST?
JZ BADSWITCH ;NO.
MOV DI,OFFSET FFLAG - 2
ADD DI,AX ;POINT TO FLAG
NOT WORD PTR [DI] ;1'S COMPLEMENT
INC BX
MOV AL,BYTE PTR [BX] ;GET NEXT CHAR. FROM LINE
COMPLIST <SPACE,TAB,NULL>,ENDSW ;IF DELIM
JMP SWLOOP ;ELSE ASSUME THIS IS A SWITCH CHAR.
ENDSW: ADD SI,2 ;POINT TO NEXT POINTER TO AN ARG
LOOP NEXTSW
ERROR 1 ;NO ARGS BESIDES SWITCHES
MOV AL,1
JMP EXIT2
BADSWITCH:
MOV AL,BYTE PTR [BX]
CALL COUT ;DISPLAY BAD CHAR.
ERROR 9 ;ILLEGAL SWITCH
MOV AL,9 ;SET EXIT CODE
JMP EXIT2
GETFILES:
CMP CX,0 ;CHECK ARGUMENT COUNT
JG ARGSOK ;IF AT LEAST 1
NOARGS:
JMP USEMSG ;GIVE USE MESSAGE
ARGSOK: MOV WORD PTR NUMARGS,CX ;SAVE NUMBER OF ARGUMENTS (LESS SWITCHES)
;*****************************************
;* LOOP, DELETING FILES IN ARGUMENT LIST *
;*****************************************
RM1ARG:
MOV BX, WORD PTR [SI] ;GET POINTER TO ARG
PUSH SI
PUSH CX
CALL RMARG ;DELETE IT
POP CX
POP SI
ADD SI,2 ;ADVANCE TO NEXT ARG POINTER
LOOP RM1ARG ;LOOP TILL NO MORE ARGS TO DELETE
MOV AL,0 ;SET EXIT CODE
JMP EXIT2
;*******************
;* REMOVE ONE FILE *
;*******************
RMARG PROC NEAR
MOV BYTE PTR DRIVE,0 ;SET DRIVE DEFAULT
MOV DI,OFFSET RSTACK+ARG ;COLLECT FILE NAME
MOV AL,[BX+1]
CMP AL,':' ;CHECK FOR DRIVE SPEC
JNE GETARG ;IF NONE
MOV AL,[BX] ;GET DRIVE LETTER
SUB AL,'A'-1 ;MAKE BINARY
MOV BYTE PTR DRIVE,AL ;SAVE DRIVE
GETARG: MOV AL,[BX] ;COPY FROM [BX] TO [DI] UNTIL DELIMITER
CMP AL,0
JE ENDARG
STOSB
INC BX
JMP GETARG
ENDARG:
STOSB ;END ARG W. ZERO
MOV WORD PTR RBASE,OFFSET RSTACK ;SAVE OFFSET TO RSTACK
CALL RMIT ;DO IT TO IT
RET
RMARG ENDP
PAGE +
;*********************************************************************
; THIS ROUTINE REMOVES A FILE OR DIRECTORY WHOSE PATHNAME IS SPECIFIED
; IN FIELD 'ARG' OF A STRUCTURE OF TYPE 'RMSTRUC'. 'RBASE' POINTS
; TO THE START OF THE DATA STRUCTURE FOR THIS RECURSION LEVEL.
;
RMIT PROC NEAR
MOV BX,WORD PTR RBASE ;GET BASE ADDR. (POINTER TO RMINFO)
ADDR DX,DTA
MOV AH,SET_DTA
INT DOS ;SET DTA
ADDR CX,SPATH
ADDR DX,SPREFIX
PUSH BX
ADD BX,ARG
CALL FIXPATH ;PARSE PATHNAME
POP BX
CMP AX,TYPE_UNK
JNE GOODPATH ;IF APPARENTLY OK
ADDR DX,ARG
CALL ERRORMSG
ERROR 2 ;NONEXISTENT PATHNAME, COMPLAIN
RET
GOODPATH:
MOV WORD PTR [BX].PATHTYPE,AX ;SAVE TYPE OF ARGUMENT
IF GOOFPROOF
CMP AX,TYPE_DSP ;DIRECTORY SPEC?
JE CHECKI ;YES, MAY NEED OK
CMP AX,TYPE_DRV ;DRIVE SPEC?
JNE NOTDRV ;NO
CHECKI:
CMP BYTE PTR IFLAG,TRUE ;I FLAG SET?
JNE GETOK ;NO, GET OK
JMP NOARGERR ;ELSE GO AHEAD
ENDIF
NOTDRV:
CMP AX,TYPE_DIR ;DIRECTORY?
JNE NOTDIR
CMP BYTE PTR RFLAG,TRUE ;R FLAG SET?
JNE DIRERR ;NO, ERROR
JMP NOARGERR ;YES, OK
DIRERR:
ADDR DX,ARG
CALL ERRORMSG ;SHOW ARGUMENT
ERROR 3 ;COMPLAIN THAT IT'S A DIRECTORY
RET
NOTDIR:
IF GOOFPROOF
CMP AX,TYPE_AFN
JNE NOARGERR ;IF NOT AFN
CMP BYTE PTR LEVEL,0
JG NOARGERR ;IF LEVEL>0, DON'T CHECK FOR *.*
CMP BYTE PTR IFLAG,TRUE
JE NOARGERR ;DITTO IF I SWITCH SPECIFIED
CALL CHECKWILD ;CHECK FOR *.*
JNC NOARGERR ;IF SOMETHING ELSE
GETOK:
; User typed something like *.* or *foo.* or A: or A:\FOO\
; In all cases make the end of the path = *.* and ask for
; confirmation.
ADDR SI,SPATH
MOV WORD PTR FNAME_START, SI
FINDFNAME:
MOV AL, BYTE PTR [SI]
CMP AL, ':'
JE FOUNDPATH
CMP AL, '\'
JE FOUNDPATH
CMP AL, 0
JE ENDOFNAME
INC SI
JMP FINDFNAME
FOUNDPATH:
INC SI
MOV WORD PTR FNAME_START, SI
JMP FINDFNAME
ENDOFNAME:
MOV DI, WORD PTR FNAME_START
MOV AL, '*'
STOSB
MOV AL, '.'
STOSB
MOV AL, '*'
STOSB
XOR AL, AL
STOSB
ADDR DX,SPATH
CALL ERRORMSG ;SHOW SEARCH PATH
ERROR 13
ERROR 6A ;USER TYPED *.*, ASK FOR CONFIRMATION
CALL GETYORN
CMP AL,'Y'
JE NOARGERR ;GO AHEAD IF 'Y' TYPED
MOV AL,13 ;SET EXIT CODE
JMP EXIT2
ENDIF
;******************************************
; SEE IF ANYTHING MATCHES THE SEARCH SPEC *
;******************************************
NOARGERR:
ADDR DX,SPATH ;POINT TO SEARCH PATH
MOV CX,31H ;SET SEARCH ATTRIBUTES
MOV AH,FIND_FIRST
INT DOS ;SEARCH FOR 1ST MATCH
JNC GOTONE ;OK IF SOMETHING FOUND
ADDR DX,ARG
CALL ERRORMSG ;ELSE SHOW ARGUMENT
ERROR 2 ;SAY IT DOESN'T EXIST
RET
;**************
; TOP OF LOOP *
;**************
GOTONE:
CALL BUILD_NAME ;MAKE UNAMBIG. FILE NAME
JNC NOSKIP
JMP NEXTFILE ;IF "FILE" IS "." OR ".."
NOSKIP:
TEST [BX].DTA+21,BIT$DIR ;IS THIS A DIRECTORY?
JNZ GOTADIR ;YES.
JMP RMFILE ;NO, IT'S A FILE
;*************************************************************
; IF ARG IS A DIRECTORY, AND R FLAG SET, DELETE ITS CONTENTS *
;*************************************************************
GOTADIR:
CMP BYTE PTR RFLAG,TRUE ;R FLAG SET?
JE RSET ;YES, OK TO DELETE DIRECTORY
JMP NEXTFILE ;NO, JUST SKIP OVER DIRECTORY
RSET:
CMP BYTE PTR IFLAG,TRUE ;I FLAG SET?
JNE INOTSET ;NO, GO INTO DIRECTORY
ADDR DX,FULLNAME
CALL ERRORMSG ;SHOW DIRECTORY NAME
ERROR 11 ;ASK IF USER WANTS TO ENTER IT
CALL GETYORN ;GET RESPONSE
CMP AL,'N'
JE NEXTFILE ;IF N TYPED
INOTSET:
CMP WORD PTR LEVEL,MAXLEVEL-1 ;ARE WE AT MAX LEVEL?
JL NOTMAX ;NO
ERROR 7 ;YES, TOO DEEP
MOV AL,7 ;SET EXIT CODE
JMP EXIT2
NOTMAX:
COPYPATH FULLNAME,(ARG+RMSTRUCSIZE) ;COPY DIRECTORY TO ARG AT NEXT LEVEL
PUSH BX ;SAVE POINTER TO BASE
INC WORD PTR LEVEL ;INCREMENT RECURSION LEVEL
ADD WORD PTR RBASE,RMSTRUCSIZE ;ADVANCE BASE POINTER
CALL RMIT ;REMOVE THE DIRECTORY CONTENTS
POP BX ;RESTORE BASE POINTER
DEC WORD PTR LEVEL ;DECREMENT RECURSION LEVEL
SUB WORD PTR RBASE,RMSTRUCSIZE ;RESTORE BASE TO PREVIOUS LEVEL
ADDR DX,DTA
MOV AH,SET_DTA
INT DOS ;RESET DTA
JMP SHORT NEXTFILE ;DO NEXT FILE
;**************************
; FOUND A FILE, REMOVE IT *
;**************************
RMFILE:
CMP BYTE PTR VFLAG,TRUE ;CHECK VERBOSE FLAG
JNE QUIET ;IF QUIET MODE
ADDR DX,FULLNAME ;NOT QUIET, SHOW VERBIAGE
CALL ERRORMSG
CALL CRLF
QUIET:
CALL RM_FILE
JNC NEXTFILE
ADDR DX,FULLNAME ;IF ERROR, SHOW NAME
ERROR 5 ;AND ERROR MSG.
;*****************
; BOTTOM OF LOOP *
;*****************
NEXTFILE:
MOV AH,FIND_NEXT
INT DOS ;FIND NEXT MATCH, IF ANY
JC NOMORE ;IF NONE
JMP GOTONE ;GOT ONE, BACK TO TOP OF LOOP
;*************************************************
; NO MORE FILES, DELETE DIRECTORY (IF NECESSARY) *
; ************************************************
NOMORE:
CMP WORD PTR [BX].PATHTYPE,TYPE_DIR ;WAS THIS ARG A DIRECTORY?
JNE DONE ;NO, DONE
CMP BYTE PTR RFLAG,TRUE ;RFLAG SET?
JNE DONE ;NO, DONE
ADDR DX,ARG ;POINT TO DIRECTORY NAME
CMP BYTE PTR IFLAG,TRUE ;I FLAG SET?
JNE NOI
CALL ERRORMSG ;DISPLAY DIRECTORY NAME
ERROR 12 ;ASK FOR OK TO DELETE
CALL GETYORN ;GET Y OR N RESPONSE
CMP AL,'N'
JE DONE ;IF N, DON'T DELETE IT
NOI:
ADDR DX,ARG
MOV AH,RMDIR
INT DOS ;REMOVE DIRECTORY (IT SHOULD BE EMPTY NOW)
JNC DONE ;IF OK
ADDR DX,ARG
CALL ERRORMSG ;ELSE SHOW DIRECTORY NAME
ERROR 5 ;AND ERROR MSG.
DONE:
RET ;ALL DONE
RMIT ENDP
;**************************************************
; CHECKWILD = CHECK ARG FOR *.* ERASURE
; RETURNS 'C' = 1 IF *.* ON WHOLE DIRECTORY OR DRIVE
CHECKWILD PROC NEAR
ADDR SI,ARG ;GET ARG
MOV WORD PTR FNAME_START, SI
FINDFN: ;FIND THE FILE NAME PORTION
CMP BYTE PTR [SI],0
JE GOTEND
CMP BYTE PTR [SI],'\'
JE PATH_CHAR
CMP BYTE PTR [SI],':'
JE PATH_CHAR
INC SI
JMP SHORT FINDFN
PATH_CHAR:
INC SI
CMP BYTE PTR [SI], 0 ; IF ARG ENDS W. \ OR :
JE WIPEOUT ; TREAT AS WILDCARD
MOV WORD PTR FNAME_START, SI
JMP SHORT FINDFN
GOTEND:
MOV SI, WORD PTR FNAME_START ; GET START OF FILE NAME
CMP BYTE PTR [SI], '*' ; IS IT STAR?
JNE NOTWIPE ; J/NO
FINDEXT:
INC SI
CMP BYTE PTR [SI], '.'
JE FOUND_EXT
CMP BYTE PTR [SI], 0
JE NOTWIPE
JMP FINDEXT
FOUND_EXT:
INC SI
CMP BYTE PTR [SI], '*'
JNE NOTWIPE
WIPEOUT:
STC
RET
NOTWIPE:
CLC
RET
CHECKWILD ENDP
PAGE +
;*****************************************************************************
; THIS ROUTINE TAKES THE INFO ON A FILE IN THE DTA AND USES IT TO GENERATE A
; FULL, UNAMBIGUOUS FILE NAME BY ADDING THE NECESSARY DIRECTORY PREFIXES TO IT.
; IT SETS THE CARRY FLAG IF THE "FILE" IS "." OR "..".
;
BUILD_NAME PROC NEAR
COPYPATH SPREFIX,FULLNAME ;GET SOURCE PREFIX, COPY TO FULL NAME
DEC DI ;BACK UP OVER NULL
ADDR SI,(DTA+30) ;POINT TO FILE NAME WE FOUND
CMP [SI],BYTE PTR '.' ;DOES IT START WITH .? -
JNE NOTDOT ;- NO
STC ;- YES, SET CARRY TO SKIP IT
RET
NOTDOT:
CALL CPYCNT ;ADD IT TO SOURCE PREFIX
CLC ;CLEAR CARRY
RET
BUILD_NAME ENDP
;*************************************************************************
; REMOVE ONE FILE (NAME IS IN FIELD 'FULLNAME' OF THE 'RMSTRUC' POINTED TO
; BY BX). RETURNS WITH CARRY SET IF ERROR.
;
RM_FILE PROC NEAR
CMP BYTE PTR IFLAG,TRUE ;IS FLAG SET TO CONFIRM?
JNE COK ;NO.
ADDR DX,FULLNAME
CALL ERRORMSG ;SHOW FILE
ERROR 4 ;ASK FOR CONFIRMATION
CALL GETYORN ;GET Y OR N RESPONSE
CMP AL,'Y' ;IS IT YES?
JNE OKEXIT ;NO, RETURN W/O ERROR
COK:
TRYAGAIN:
ADDR DX,FULLNAME
MOV AH,UNLINK
INT DOS ;UNLINK THAT SUCKER
JNC OKEXIT ;IF NO PROBLEM
CMP AX,5 ;WAS FILE R/O? (THIS OUGHT TO BE
; THE ONLY POSSIBLE ERROR)
JNE ABEXIT ;EXIT IF SOME OTHER ERROR
CMP BYTE PTR FFLAG,TRUE ;CHECK F FLAG
JE NOWARN ;IF SET, DON'T WARN ABOUT R/O FILE
ADDR DX,FULLNAME
CALL ERRORMSG ;SHOW FILE NAME
ERROR 6 ;R/O FILE, QUERY USER AGAIN
CALL GETYORN ;GET Y OR N RESPONSE
CMP AL,'Y' ;TEST FOR 'Y' RESPONSE
JNE OKEXIT ;QUIT (WITH NO ERROR) IF USER SAYS 'N'
NOWARN:
MOV CX,0 ;'Y' TYPED CLEAR ALL ATTRIBUTES
ADDR DX,FULLNAME ;POINT TO FILE NAME
MOV AH,CHMOD
MOV AL,1 ;CHANGE ATTRIBUTES
INT DOS ;TRY MAKING IT R/W
JMP TRYAGAIN ;TRY TO ERASE IT AGAIN
ABEXIT: STC
RET
OKEXIT: CLC
RET
RM_FILE ENDP
EXIT2:
MOV AH,EXIT
INT DOS ;EXIT TO DOS
END ENTRY